package com.sudo.api._admin;

import com.sudo.common.annotation.ApiIdempotent;
import com.sudo.common.annotation.ApiAuthorization;
import com.sudo.common.enums.SysJobStatus;
import com.sudo.common.task.TaskUtil;
import com.sudo.common.utils.HttpUserInfoUtil;
import com.sudo.common.utils.JsonRes;
import com.sudo.common.utils.JsonUtil;
import com.sudo.common.utils.PagedGridResult;
import com.sudo.dao.admin.entity.SysServerNodeJob;
import com.sudo.dao.admin.entity.SysServerNodeTask;
import com.sudo.dao.admin.model.bo.SysRunServerNodeJobBO;
import com.sudo.dao.admin.model.bo.SysServerNodeJobBO;
import com.sudo.rpc.api.utils.RpcRes;
import com.sudo.service.admin.service.SysServerNodeJobService;
import com.sudo.service.admin.service.SysServerNodeTaskService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Map;

@Slf4j
@Api(value = "Rpc定时任务接口",tags = {"Rpc定时任务管理相关的接口"})
@RestController
@RequestMapping("sysServerNodeJob")
public class SysServerNodeJobController extends AdminBaseController{

    @Resource
    private SysServerNodeJobService sysServerNodeJobService;

    @Resource
    private SysServerNodeTaskService sysServerNodeTaskService;


    @ApiOperation(value = "分页查询Rpc定时任务",notes = "分页查询Rpc定时任务",httpMethod = "POST")
    @PostMapping("/querySysServerNodeJobByPage")
    public JsonRes querySysServerNodeJobByPage(@RequestBody SysServerNodeJobBO sysServerNodeJobBO) {
        PagedGridResult pagedGridResult = sysServerNodeJobService.querySysServerNodeJobByPage(sysServerNodeJobBO);
        return JsonRes.ok(pagedGridResult);
    }

    @ApiAuthorization(menu = "serverNodeJob",button = "detail")
    @ApiOperation(value = "查询定时任务",notes = "查询定时任务",httpMethod = "GET")
    @GetMapping("/querySysServerNodeJobById")
    public JsonRes querySysServerNodeJobById(@RequestParam(value = "id",required = true)Integer id) {
        SysServerNodeJob sysServerNodeJob = sysServerNodeJobService.querySysServerNodeJobById(id);
        return JsonRes.ok(sysServerNodeJob);
    }

    @ApiIdempotent
    @ApiAuthorization(menu = "serverNodeJob",button = "add")
    @ApiOperation(value = "创建方法任务",notes = "创建方法任务",httpMethod = "POST")
    @PostMapping("/saveSysServerNodeJob")
    public JsonRes saveSysServerNodeJob(@RequestBody @Valid SysServerNodeJobBO sysServerNodeJobBO,
                                    BindingResult result,
                                    HttpServletRequest request) {
        if (result.hasErrors()) {
            return JsonRes.errorMsg(getFirstError(result));
        }
        boolean validExpression = CronExpression.isValidExpression(sysServerNodeJobBO.getCronExpression());
        if (!validExpression) {
            return JsonRes.errorMsg("cron表达式不正确");
        }
        SysServerNodeTask sysServerNodeTask = sysServerNodeTaskService.getSysServerNodeTask(
                sysServerNodeJobBO.getServer(), sysServerNodeJobBO.getBeanName(), sysServerNodeJobBO.getMethodName());
        if (sysServerNodeTask == null){
            return JsonRes.errorMsg("不存在任务 "+ sysServerNodeJobBO.getServer()
                    + "-" + sysServerNodeJobBO.getBeanName()
                    + "-" + sysServerNodeJobBO.getMethodName());
        }else {
            if (StringUtils.isNotBlank(sysServerNodeTask.getMethodParams())) {
                Map<String,Object> paramMap = JsonUtil.jsonToPojo(sysServerNodeJobBO.getMethodParams(), Map.class);
                if (null == paramMap) {
                    return JsonRes.errorMsg("参数格式异常，请保持Json对象格式");
                }
                boolean paramStatus = TaskUtil.verifyParam(sysServerNodeTask.getMethodParams(),paramMap);
                if (!paramStatus){
                    return JsonRes.errorMsg("参数格式异常，请严格遵从参数类型、是否必填");
                }
            }
        }
        String sessionUser = HttpUserInfoUtil.getSessionUser(request);
        int affectCount = sysServerNodeJobService.saveSysServerNodeJob(sysServerNodeJobBO, sessionUser);
        return JsonRes.judge(affectCount, "新增成功", "新增失败");
    }

    @ApiIdempotent
    @ApiAuthorization(menu = "serverNodeJob",button = "update")
    @ApiOperation(value = "修改定时任务状态",notes = "修改定时任务状态",httpMethod = "POST")
    @PostMapping("/updateSysServerNodeJobStatus")
    public JsonRes updateSysServerNodeJobStatus(@RequestBody SysServerNodeJobBO sysServerNodeJobBO) {
        int affectCount = sysServerNodeJobService.updateSysServerNodeJobStatus(sysServerNodeJobBO);
        return JsonRes.judge(affectCount, "修改成功", "修改失败");
    }

    @ApiIdempotent
    @ApiAuthorization(menu = "serverNodeJob",button = "update")
    @ApiOperation(value = "编辑定时任务（不包括状态）",notes = "编辑定时任务（不包括状态）",httpMethod = "POST")
    @PostMapping("/updateSysServerNodeJobWithNoStatus")
    public JsonRes updateSysServerNodeJobWithNoStatus(@RequestBody @Valid SysServerNodeJobBO sysServerNodeJobBO,
                                                  BindingResult result) {
        SysServerNodeJob sysServerNodeJob = sysServerNodeJobService.querySysServerNodeJobById(sysServerNodeJobBO.getId());
        if (SysJobStatus.RUN.name().equals(sysServerNodeJob.getStatus())) {
            return JsonRes.errorMsg("修改任务前必须停止该任务");
        }
        if (result.hasErrors()) {
            return JsonRes.errorMsg(getFirstError(result));
        }
        boolean validExpression = CronExpression.isValidExpression(sysServerNodeJobBO.getCronExpression());
        if (!validExpression) {
            return JsonRes.errorMsg("cron表达式不正确");
        }
        SysServerNodeTask sysServerNodeTask = sysServerNodeTaskService.getSysServerNodeTask(
                sysServerNodeJobBO.getServer(), sysServerNodeJobBO.getBeanName(), sysServerNodeJobBO.getMethodName());
        if (sysServerNodeTask == null){
            return JsonRes.errorMsg("不存在任务 "+ sysServerNodeJobBO.getServer()
                    + "-" + sysServerNodeJobBO.getBeanName()
                    + "-" + sysServerNodeJobBO.getMethodName());
        }else {
            if (StringUtils.isNotBlank(sysServerNodeTask.getMethodParams())) {
                Map<String,Object> paramMap = JsonUtil.jsonToPojo(sysServerNodeJobBO.getMethodParams(), Map.class);
                if (null == paramMap) {
                    return JsonRes.errorMsg("参数格式异常，请保持Json对象格式");
                }
                boolean paramStatus = TaskUtil.verifyParam(sysServerNodeTask.getMethodParams(),paramMap);
                if (!paramStatus){
                    return JsonRes.errorMsg("参数格式异常，请严格遵从参数类型、是否必填");
                }
            }
        }
        int affectCount = sysServerNodeJobService.updateSysServerNodeJobWithNoStatus(sysServerNodeJobBO);
        return JsonRes.judge(affectCount, "修改成功", "修改失败");
    }

    @ApiIdempotent
    @ApiAuthorization(menu = "serverNodeJob",button = "delete")
    @ApiOperation(value = "删除定时任务",notes = "删除定时任务",httpMethod = "POST")
    @PostMapping("/deleteSysServerNodeJob")
    public JsonRes deleteSysServerNodeJob(@RequestParam Integer id) {
        SysServerNodeJob sysServerNodeJob = sysServerNodeJobService.querySysServerNodeJobById(id);
        if (SysJobStatus.RUN.name().equals(sysServerNodeJob.getStatus())) {
            return JsonRes.errorMsg("删除任务前必须停止该任务");
        }
        int affectCount = sysServerNodeJobService.deleteSysServerNodeJob(id);
        return JsonRes.judge(affectCount, "删除成功", "删除失败");
    }

    @ApiIdempotent
    @ApiAuthorization(menu = "serverNodeJob", button = "run")
    @ApiOperation(value = "运行一次任务", notes = "运行一次任务", httpMethod = "POST")
    @PostMapping("/runSysServerNodeJob")
    public RpcRes runSysServerNodeJob(@RequestBody SysRunServerNodeJobBO sysRunServerNodeJobBO) throws Exception {
        SysServerNodeJob sysServerNodeJob = sysServerNodeJobService.querySysServerNodeJobById(sysRunServerNodeJobBO.getId());

        SysServerNodeTask sysServerNodeTask = sysServerNodeTaskService.getSysServerNodeTask(
                sysServerNodeJob.getServer(), sysServerNodeJob.getBeanName(), sysServerNodeJob.getMethodName());
        if (sysServerNodeTask == null){
            return RpcRes.errorMsg("不存在任务 "+ sysServerNodeJob.getServer()
                    + "-" + sysServerNodeJob.getBeanName()
                    + "-" + sysServerNodeJob.getMethodName());
        }else {
            if (StringUtils.isNotBlank(sysServerNodeTask.getMethodParams())) {
                Map<String,Object> paramMap = JsonUtil.jsonToPojo(sysRunServerNodeJobBO.getMethodParams(), Map.class);
                if (null == paramMap) {
                    return RpcRes.errorMsg("参数格式异常，请保持Json对象格式");
                }
                boolean paramStatus = TaskUtil.verifyParam(sysServerNodeTask.getMethodParams(),paramMap);
                if (!paramStatus){
                    return RpcRes.errorMsg("参数格式异常，请严格遵从参数类型、是否必填");
                }
            }
        }
        return sysServerNodeJobService.callTaskMethod(sysServerNodeJob, sysRunServerNodeJobBO);
    }

}
